package cn.shanguoyu.base.springboot.starter.limit.manager.abs;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.net.Ipv4Util;
import cn.hutool.core.util.StrUtil;
import cn.shanguoyu.base.springboot.starter.limit.enums.LimitType;
import cn.shanguoyu.base.springboot.starter.limit.manager.pojo.Limiter;
import cn.shanguoyu.base.springboot.starter.web.toolkit.IpUtil;
import cn.shanguoyu.base.springboot.starter.web.toolkit.MvcUtil;

/**
 * @description:抽象基本逻辑
 * @author：sgy
 * @date: 2023-05-29
 */
public abstract class AbstractLimiterManager implements LimiterManager {

    @Override
    public boolean tryAccess(Limiter limiter) {
        // 根据请求限流类型重置里面的key
        rebuildKey(limiter);
        return limit(limiter);
    }

    /**
     * 根据请求限流类型重置里面的key
     *
     * @param limiter
     */
    private void rebuildKey(Limiter limiter) {
        // 获取请求限流类型
        LimitType limitType = limiter.getLimitType();
        // 不同类型做出不同的处理
        switch (limitType) {
            case GLOBAL:

                break;
            case IP:
                long ipv4ToLong = Ipv4Util.ipv4ToLong(IpUtil.getIpAddr1(MvcUtil.getHttpRequest()));
                String key = StrUtil.join(limiter.getKey(), StrUtil.COLON, Convert.toStr(ipv4ToLong));
                limiter.setKey(key);
                break;
        }
        // 拼接prefix
        if (StrUtil.isNotBlank(limiter.getPrefix())) {
            limiter.setKey(StrUtil.join(limiter.getPrefix(), StrUtil.COLON, limiter.getKey()));
        }
    }

    /**
     * 模板子类方法
     *
     * @param limiter
     * @return
     */
    public abstract boolean limit(Limiter limiter);
}
